home *** CD-ROM | disk | FTP | other *** search
/ Aminet 40 / Aminet 40 (2000)(Schatztruhe)[!][Dec 2000].iso / Aminet / util / arc / xadmaster.lha / xad / Developer / Sources / clients / PackDev.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-08-31  |  8.5 KB  |  301 lines

  1. #ifndef XADMASTER_PACKDEV_C
  2. #define XADMASTER_PACKDEV_C
  3.  
  4. /* Programmheader
  5.  
  6.     Name:        PackDev.c
  7.     Main:        xadmaster
  8.     Versionstring:    $VER: PackDev.c 1.4 (29.08.1999)
  9.     Author:        SDI
  10.     Distribution:    Freeware
  11.     Description:    PackDev disk archiver client
  12.  
  13.  1.0   13.06.98 : first version
  14.  1.1   13.02.99 : started again with that client
  15.  1.2   20.06.99 : removed exec.library calls
  16.  1.3   29.06.99 : now uses master free stuff
  17.  1.4   29.08.99 : now uses xdi_DataPos
  18. */
  19.  
  20. /* For now SectorLabel information is ignored, as current
  21. xadmaster.library does not support SectorLabels. */
  22.  
  23. #include <proto/xadmaster.h>
  24. #include <devices/trackdisk.h>
  25. #include "SDI_compiler.h"
  26. #define SDI_TO_ANSI
  27. #include "SDI_ASM_STD_protos.h"
  28. #include "xadXPK.c"
  29.  
  30. #ifndef XADMASTERFILE
  31. #define PackDev_Client        FirstClient
  32. #define NEXTCLIENT        0
  33. #define XADMASTERVERSION    8
  34. UBYTE version[] = "$VER: PackDev 1.4 (29.08.1999)";
  35. #endif
  36. #define PACKDEV_VERSION        1
  37. #define PACKDEV_REVISION    4
  38.  
  39. struct PackDevHead {
  40.   UBYTE        pd_Header[4];    /* equals 'PKD\x13' */
  41.   ULONG        pd_BlockNum;    /* Number of blocks */
  42.   ULONG        pd_BlockSize;    /* size of one block */
  43.   ULONG        pd_Reserved;    /* Reserved blocks */
  44.   ULONG        pd_TrackLength;    /* Length of one track*/
  45.   ULONG        pd_xpkBufferSize; /* in byte */
  46.   ULONG        pd_xpkPacker;    /* XPK packer type */
  47.   ULONG pad1;    /* These are fields containing the XPK packer name */
  48.   ULONG pad2;    /* Don't know, why the author used 24bytes instead */
  49.   ULONG pad3;    /* of the required 4. */
  50.   ULONG pad4;    /* The fields are ignored by that client */
  51.   ULONG pad5;
  52.   UWORD        pd_xpkMode;     /* XPK mode Number 0..100 */
  53.   UWORD        pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
  54. };
  55.  
  56. struct PackDevHeadOld {
  57.   UBYTE        pd_Header[4];    /* equals 'PKD\x11' */
  58.   ULONG        pd_BlockNum;    /* Number of blocks */
  59.   ULONG        pd_BlockSize;    /* size of one block */
  60.   ULONG        pd_Reserved;    /* Reserved blocks */
  61.   ULONG        pd_TrackLength;    /* Length of one track*/
  62.   ULONG        pd_xpkBufferSize; /* in byte */
  63.   ULONG        pd_xpkPacker;    /* XPK packer type */
  64.   UWORD        pd_xpkMode;     /* XPK mode Number 0..100 */
  65.   UWORD        pd_KnownFileSys; /* When all data stored, this is 0, else 1 */
  66. };
  67.  
  68. /* Every block has following structure:
  69.  ULONG size
  70.  ULONG data[...]
  71.  ULONG checksum
  72.  
  73. Where data are the blocks and additionally the SectorLabels (16 Byte).
  74. NOTE: xadmaster does not support to extract the label data in current version!
  75.  
  76. Checksum is missing in PackDev11 Version.
  77. */
  78.  
  79. #define PKD_XPKPACKED    (1<<0)
  80. #define PKD_OLDMODE    (1<<1)
  81.  
  82. ASM(BOOL) PackDev_RecogData(REG(d0, ULONG size), REG(a0, STRPTR data),
  83. REG(a6, struct xadMasterBase *xadMasterBase))
  84. {
  85.   if(((ULONG *)data)[0] == 0x504B4413 || ((ULONG *)data)[0] == 0x504B4411)
  86.     return 1;
  87.   else
  88.     return 0;
  89. }
  90.  
  91. static LONG PKDdecrBuf(STRPTR *buf, ULONG *i, struct xadArchiveInfo *ai,
  92. struct xadMasterBase *xadMasterBase, ULONG oldmode)
  93. {
  94.   LONG err, size;
  95.   if(!(err = xadHookAccess(XADAC_READ, 4, &size, ai)))
  96.   {
  97.     if(!(err = xpkDecrunch(buf, i, ai, xadMasterBase)))
  98.     {
  99.       if(!oldmode)
  100.         err = xadHookAccess(XADAC_READ, 4, &size, ai);
  101.     }
  102.   }
  103.   return err;
  104. }
  105.  
  106. /* maybe there are some errors in that code, not tested yet */
  107. ASM(LONG) PackDev_GetInfo(REG(a0, struct xadArchiveInfo *ai),
  108. REG(a6, struct xadMasterBase *xadMasterBase))
  109. {
  110.   struct PackDevHead h;
  111.   LONG err;
  112.  
  113.   if(!(err = xadHookAccess(XADAC_READ, sizeof(struct PackDevHeadOld), &h, ai)))
  114.   {
  115.     if(h.pd_Header[3] == 0x11 || !(err = xadHookAccess(XADAC_READ,
  116.     sizeof(struct PackDevHead)-sizeof(struct PackDevHeadOld), ((STRPTR) &h) +
  117.     sizeof(struct PackDevHeadOld), ai)))
  118.     {
  119.       struct xadDiskInfo *xdi;
  120.       ULONG blksiz = 0, i, dat[10], spos;
  121.       STRPTR buf = 0;
  122.  
  123.       if(h.pd_Header[3] == 0x11)
  124.       {
  125.         h.pd_KnownFileSys = ((struct PackDevHeadOld *) &h)->pd_KnownFileSys;
  126. /*      h.pd_xpkMode = ((struct PackDevHeadOld *) &h)->pd_xpkMode; */
  127.       }
  128.     
  129.       /* check for password flag */
  130.       if(h.pd_xpkPacker && !err && !(err = xadHookAccess(XADAC_READ, 40, dat, ai))
  131.       && !(err = xadHookAccess(XADAC_INPUTSEEK, -40, 0, ai)))
  132.       {
  133.         if(dat[9] & (1<<25))
  134.           ai->xai_Flags |= XADAIF_CRYPTED;
  135.       }
  136.  
  137.       spos = ai->xai_InPos;
  138.       
  139.       if(h.pd_KnownFileSys)
  140.       {
  141.         blksiz = h.pd_BlockNum;
  142.         if(h.pd_xpkPacker)
  143.           err = PKDdecrBuf(&buf, &i, ai, xadMasterBase, h.pd_Header[3] == 0x11);
  144.         else
  145.         {
  146.           if(!(buf = (STRPTR) xadAllocVec((i = blksiz>>3), MEMF_ANY)))
  147.             err = XADERR_NOMEMORY;
  148.           else
  149.             err = xadHookAccess(XADAC_READ, i, buf, ai);
  150.         }
  151.       }
  152.     
  153.       if(!err)
  154.       {
  155.         if((xdi = (struct xadDiskInfo *) xadAllocObject(XADOBJ_DISKINFO,
  156.         blksiz ? XAD_OBJBLOCKENTRIES : TAG_DONE, blksiz, TAG_DONE)))
  157.         {
  158.           if(ai->xai_Flags & XADAIF_CRYPTED)
  159.             xdi->xdi_Flags |= XADDIF_CRYPTED;
  160.           xdi->xdi_Flags |= XADDIF_NOCYLINDERS|XADDIF_NOLOWCYL|XADDIF_SEEKDATAPOS|
  161.                         XADDIF_NOHIGHCYL|XADDIF_NOHEADS|XADDIF_NOCYLSECTORS;
  162.           xdi->xdi_TotalSectors = h.pd_BlockNum;
  163.           xdi->xdi_SectorSize = h.pd_BlockSize;
  164.           xdi->xdi_TrackSectors = h.pd_TrackLength / h.pd_BlockSize;
  165.           xdi->xdi_EntryNumber = 1;
  166.           xdi->xdi_DataPos = spos;
  167.           i = 0;
  168.           if(h.pd_xpkPacker)
  169.             i |= PKD_XPKPACKED;
  170.           if(h.pd_Header[3] == 0x11)
  171.             i |= PKD_OLDMODE;
  172.           xdi->xdi_PrivateInfo = (APTR) i;
  173.           ai->xai_DiskInfo = xdi;
  174.  
  175.       /* does nothing if blksiz == 0 */
  176.       for(i = 0; i < blksiz; ++i)
  177.           {
  178.             if(i < h.pd_Reserved || (buf[i/8] & ((1 << (7-(i%8))))))
  179.               xdi->xdi_BlockInfo[i] |= XADBIF_CLEARED;
  180.           }
  181.         }
  182.         else
  183.           err = XADERR_NOMEMORY;
  184.       }
  185.       if(buf)
  186.         xadFreeObjectA(buf, 0);
  187.     }
  188.   }
  189.  
  190.   return err;
  191. }
  192.  
  193. ASM(LONG) PackDev_UnArchive(REG(a0, struct xadArchiveInfo *ai),
  194. REG(a6, struct xadMasterBase *xadMasterBase))
  195. {
  196.   ULONG i, j, trsec, numsecs = 0;
  197.   LONG err = 0, secsize;
  198.   struct xadDiskInfo *di;
  199.   STRPTR temp;
  200.   
  201.   di = ai->xai_CurDisk;
  202.   secsize = di->xdi_SectorSize;
  203.   trsec = di->xdi_TrackSectors;
  204.  
  205.   if(!(temp = xadAllocVec(di->xdi_SectorSize*di->xdi_TrackSectors, MEMF_ANY)))
  206.     return XADERR_NOMEMORY;
  207.  
  208.   if(!(((ULONG) di->xdi_PrivateInfo) & PKD_XPKPACKED))
  209.   {
  210.     numsecs = 0;
  211.     for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
  212.     {
  213.       j = (i % trsec)*secsize;
  214.     
  215.       if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
  216.         memset(temp+j, 0, secsize);
  217.       else
  218.       {
  219.         err = xadHookAccess(XADAC_READ, secsize, temp+j, ai);
  220.         ++numsecs;
  221.       }
  222.       /* skip the sectorlabel and write data */
  223.       if((i % trsec) == (trsec-1) && !err)
  224.       {
  225.         if(!numsecs || !(err = xadHookAccess(XADAC_INPUTSEEK, TD_LABELSIZE*numsecs, 0, ai)))
  226.           err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
  227.         numsecs = 0;
  228.       }
  229.     }
  230.   }
  231.   else
  232.   {
  233.     ULONG size;
  234.     LONG pos = 0, ressize;
  235.     STRPTR buf = 0;
  236.  
  237.     err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
  238.     (((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE));
  239.  
  240.     if(di->xdi_BlockInfo)
  241.       pos += di->xdi_TotalSectors>>3;
  242.  
  243.     for(i = 0; !err && i < di->xdi_TotalSectors; ++i)
  244.     {
  245.       j = (i % trsec)*secsize;
  246.       
  247.       if(di->xdi_BlockInfo && di->xdi_BlockInfo[i])
  248.         memset(temp+j, 0, secsize);
  249.       else
  250.       {
  251.         ++numsecs;
  252.         if((ressize = size-pos) >= secsize)
  253.         {
  254.           xadCopyMem(buf+pos, temp+j, secsize);
  255.           pos += secsize;
  256.         }
  257.         else
  258.         {
  259.           if(ressize > 0)
  260.           {
  261.             xadCopyMem(buf+pos, temp+j, ressize);
  262.             pos += ressize;
  263.           }
  264.           else if(ressize < 0)
  265.             ressize = 0;
  266.           xadFreeObjectA(buf, 0);
  267.           buf = 0;
  268.           pos -= size;
  269.           if(!(err = PKDdecrBuf(&buf, &size, ai, xadMasterBase,
  270.           (((ULONG) di->xdi_PrivateInfo) & PKD_OLDMODE))))
  271.           {
  272.             xadCopyMem(buf+pos, temp+j+ressize, secsize-ressize);
  273.             pos += secsize-ressize;
  274.           }
  275.         }
  276.       }
  277.       /* skip the sectorlabel and write data */
  278.       if((i % trsec) == (trsec-1) && !err)
  279.       {
  280.         pos += TD_LABELSIZE*numsecs;
  281.         err = xadHookAccess(XADAC_WRITE, trsec*secsize, temp, ai);
  282.         numsecs = 0;
  283.       }
  284.     }
  285.     if(buf)
  286.       xadFreeObjectA(buf, 0);
  287.   }
  288.  
  289.   xadFreeObjectA(temp, 0);
  290.  
  291.   return err;
  292. }
  293.  
  294. const struct xadClient PackDev_Client = {
  295. NEXTCLIENT, XADCLIENT_VERSION, XADMASTERVERSION, PACKDEV_VERSION, PACKDEV_REVISION,
  296. 4, XADCF_DISKARCHIVER|XADCF_FREEDISKINFO, XADCID_PACKDEV, "PackDev",
  297. (BOOL (*)()) PackDev_RecogData, (LONG (*)()) PackDev_GetInfo,
  298. (LONG (*)()) PackDev_UnArchive, 0};
  299.  
  300. #endif /* XADASTER_PACKDEV_C */
  301.